package com.program.houai.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.program.houai.entity.*;
import com.program.houai.exception.BusinessException;
import com.program.houai.exception.ErrorType;
import com.program.houai.mapper.OrderRoyaltyMapper;
import com.program.houai.mapper.UserMapper;
import com.program.houai.redis.RedisLock;
import com.program.houai.service.*;
import com.program.houai.util.DateFullUtils;
import com.program.houai.vo.UserOrderVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version v1.0
 * @ProjectName: EOrder-master
 * @ClassName: OrderRoyaltyServiceImpl
 * @Description: TODO(一句话描述该类的功能)
 * @Author: Topcheer
 * @Date: 2024/8/29 22:25
 */
@Service
@Slf4j
public class OrderRoyaltyServiceImpl extends ServiceImpl<OrderRoyaltyMapper, OrderRoyaltyEntity> implements IOrderRoyaltyService {

    @Autowired
    private RedisLock redisLock;
    @Autowired
    private IUserService userService;
    @Value("${system.order.royaltyDay}")
    private  int royaltyDay;

    @Autowired
    private IUserRoyaltyService userRoyaltyService ;

    @Value("${system.order.royalty}")
    private int royalty;

    @Autowired
    private IUserWithdrawService userWithdrawService;

    @Autowired
    private IVipCardOrderService vipCardOrderService;

    @Override
    @Transactional
    public void saveRoyaltyOrder() {
        String lockKey = "royalty";
        long expireTime = 10000;
        String requestId = "royalty";
        //获取到锁
        if (redisLock.tryLock(lockKey,expireTime,requestId)){
            try {
                saveOrderRoyalty();
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }finally {
                redisLock.unlock(lockKey,requestId);
            }
        }else{
            log.info("未获取到锁");
        }
    }

    @Override
    @Transactional
    public void saveUserOrderRoyalty() {
        String lockKey = "userRoyalty";
        long expireTime = 10000;
        String requestId = "userRoyalty";
        //获取到锁
        if (redisLock.tryLock(lockKey,expireTime,requestId)){
            try {
                saveUserRoyalty();
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }finally {
                redisLock.unlock(lockKey,requestId);
            }
        }else{
            log.info("未获取到锁");
        }
    }

    // 1 插入结算订单
    // 2 计算佣金
    public void  saveOrderRoyalty(){
        String startTime = DateFullUtils.getDateStr(DateFullUtils.diffDate(new Date(),royaltyDay),DateFullUtils.YY_MM_DD)+" 23:59:59";
        //查询未结算的订单
        List<UserOrderVO> orderList =  userService.getAllOrderList(null,2,"0",startTime,null);
        List<OrderRoyaltyEntity>  royaltyList = new ArrayList<>();
        for (UserOrderVO userOrderVO :orderList){
            OrderRoyaltyEntity  orderRoyaltyEntity = new OrderRoyaltyEntity();
            orderRoyaltyEntity.setUserId(userOrderVO.getMemberId());
            orderRoyaltyEntity.setTxnNo(userOrderVO.getOrderNumber());
            orderRoyaltyEntity.setType(userOrderVO.getType());
            orderRoyaltyEntity.setTxnDesc(userOrderVO.getTxndesc());
            orderRoyaltyEntity.setPrice(userOrderVO.getPrice());
            orderRoyaltyEntity.setPayTime(userOrderVO.getPaytime());
            orderRoyaltyEntity.setNumber(userOrderVO.getNumber());
            orderRoyaltyEntity.setIsRoyalty(0);
            orderRoyaltyEntity.setCreateTime(new Date());
            royaltyList.add(orderRoyaltyEntity);
        }
        if (!royaltyList.isEmpty()){
            this.saveBatch(royaltyList);
        }
    }

    public  void saveUserRoyalty() {
        QueryWrapper<OrderRoyaltyEntity> wrap = new QueryWrapper<OrderRoyaltyEntity>();
        wrap.eq("is_royalty", 0);
        List<OrderRoyaltyEntity> list = this.list(wrap);
        Map<Integer, List<OrderRoyaltyEntity>> orderMap = list.stream()
                .collect(Collectors.groupingBy(OrderRoyaltyEntity::getUserId));
        for (Map.Entry<Integer, List<OrderRoyaltyEntity>> entry : orderMap.entrySet()) {
            Integer userId = entry.getKey();
            List<OrderRoyaltyEntity> orderRoyaltyEntityList = entry.getValue();
            UserEntity userEntity = userService.getById(userId);
            if (userEntity == null || userEntity.getPid() == null) {
                //没有上级用户修改结算订单
                for (OrderRoyaltyEntity orderRoyaltyEntity : orderRoyaltyEntityList) {
                    orderRoyaltyEntity.setIsRoyalty(3);
                    orderRoyaltyEntity.setUpdateTime(new Date());
                }
                this.updateBatchById(orderRoyaltyEntityList);
            } else {
                QueryWrapper<UserRoyaltyEntity> royaltyEntityWrap = new QueryWrapper<UserRoyaltyEntity>();
                royaltyEntityWrap.eq("user_id", userEntity.getPid());
                UserRoyaltyEntity userRoyaltyEntity = userRoyaltyService.getOne(royaltyEntityWrap);
                int userRoyalty = royalty;
                if (userRoyaltyEntity != null) {
                    userRoyalty = userRoyaltyEntity.getRoyalty();
                }
                UserEntity userEntity1 = userService.getById(userEntity.getPid());
                int totalMoney = 0;
                if (userEntity1 != null) {
                    for (OrderRoyaltyEntity orderRoyaltyEntity : orderRoyaltyEntityList) {
                        BigDecimal divisor = BigDecimal.valueOf(100);
                        //佣金
                        BigDecimal dividend = BigDecimal.valueOf(orderRoyaltyEntity.getPrice() * userRoyalty);
                        BigDecimal yuan = dividend.divide(divisor, 2, RoundingMode.HALF_UP);
                        orderRoyaltyEntity.setRoyaltyPrice(yuan.intValue());
                        totalMoney +=  yuan.intValue();
                        //计算个人账号发生额
                        UserWithdrawEntity userWithdrawEntity = new UserWithdrawEntity();
                        userWithdrawEntity.setUserId(userEntity1.getId());
                        userWithdrawEntity.setCreateTime(new Date());
                        userWithdrawEntity.setUpdateTime(new Date());
                        userWithdrawEntity.setIsCheck(1);
                        userWithdrawEntity.setServiceCharge(0);
                        //发生额
                        userWithdrawEntity.setWithdrawAmount(yuan.intValue());
                        userWithdrawEntity.setBalance(userEntity1.getMoney() + totalMoney);
                        userWithdrawEntity.setType(1);
                        userWithdrawService.save(userWithdrawEntity);
                        orderRoyaltyEntity.setIsRoyalty(1);
                        orderRoyaltyEntity.setUpdateTime(new Date());
                    }
                    //更新订单结算状态
                    updateBatchById(orderRoyaltyEntityList);
                    //更新个人余额
                    int ye = totalMoney + userEntity1.getMoney();
                    int yeResult = userService.updateUserMoney(userEntity1.getId(), userEntity1.getMoney(), ye);
                    if (yeResult < 1) {
                        throw new BusinessException(ErrorType.BIZ_ERROR, "计算佣金异常！");
                    }
                }
            }
        }
    }


    @Override
    @Transactional
    public void updateUserOrder() {
        String lockKey = "userOrderStatus";
        long expireTime = 10000;
        String requestId = "userOrderStatus";
        //获取到锁
        if (redisLock.tryLock(lockKey,expireTime,requestId)){
            try {
                updateStatus();
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }finally {
                redisLock.unlock(lockKey,requestId);
            }
        }else{
            log.info("未获取到锁");
        }
    }

    public  void updateStatus() {
        QueryWrapper<VipCardOrderEntity> wrap = new QueryWrapper<VipCardOrderEntity>();
        wrap.eq("txn_status", 0);
        wrap.le("expiration_time", new Date());
        List<VipCardOrderEntity> list = vipCardOrderService.list(wrap);
        for (VipCardOrderEntity vipCardOrderEntity :list){
            vipCardOrderEntity.setTxnStatus(99);
            vipCardOrderEntity.setUpdateTime(new Date());
        }
        vipCardOrderService.updateBatchById(list);
    }

}
